package com.a918.util;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

import static org.apache.commons.codec.digest.DigestUtils.sha256;

/**
 * @author Andybin
 */
public class ParamUtil {

    public static String loginAccessToken;

    /** 生产环境 **/
    public static String secret = "2Qtu7g0NJvOb88FcA7yy1c9FU3bJmowl";
    public static String APP_ID = "1630547304412";
    public static String CLIENT_ID = "sdHQ0A4wIzUwitSuyaQdxSoD";
    public static String TIMESTAMP = "20221015104237";
    public static String SIGN_TYPE = "SHA256";
    public static String NONCE = "33908665a78347a38f0e883ed805b54b";


//    /** 测试环境 **/
//    public static String secret = "qWqMgUw9mc2bVa9u3ENfZDPsFJDKDmhZ";
//    public static String APP_ID = "1630547194897";
//    public static String CLIENT_ID = "UUDAX5Tb0tnUnh1883w5NQqr";
//    public static String TIMESTAMP = "20211115104237";
//    public static String SIGN_TYPE = "SHA256";
//    public static String NONCE = "zwfz1oldtv";


    public static final int BASE_WORK_LENGTH = 22 * 10;

    public static String executePostRequest(String url, JSONObject bizContent) {
        String sign = ParamUtil.getSign(bizContent);
        HttpRequest httpRequest = HttpRequest.post(url);
        appendCommonParam(httpRequest);
        return httpRequest.form("SIGN", sign)
                .form("bizContent", JSONUtil.toJsonPrettyStr(bizContent))
                .execute().body();
    }

    public static String executePostRequestWithToken(String url, JSONObject bizContent) {
        String sign = getSignWithToken(bizContent);
        HttpRequest httpRequest = HttpRequest.post(url);
        appendCommonParamWithToken(httpRequest);
        return httpRequest.form("SIGN", sign)
                .form("bizContent", JSONUtil.toJsonPrettyStr(bizContent))
                //.header("Authorization", "Bearer " + loginAccessToken)
                .execute().body();
    }

    public static String executePostRequestWithToken(String url, List<JSONObject> bizContent) {
        String sign = getSign(JSONUtil.toJsonPrettyStr(bizContent));
        HttpRequest httpRequest = HttpRequest.post(url);
        appendCommonParam(httpRequest);
        return httpRequest.form("SIGN", sign)
                .form("bizContent", JSONUtil.toJsonPrettyStr(bizContent))
                .header("Authorization", "Bearer " + loginAccessToken)
                .execute().body();
    }

    public static void appendCommonParam(HttpRequest httpRequest) {
        httpRequest.form("APP_ID", APP_ID)
                .form("TIMESTAMP", TIMESTAMP)
                .form("SIGN_TYPE", SIGN_TYPE)
                .form("NONCE", NONCE);
    }

    public static void appendCommonParamWithToken(HttpRequest httpRequest) {
        httpRequest.form("APP_ID", APP_ID)
                .form("TIMESTAMP", TIMESTAMP)
                .form("SIGN_TYPE", SIGN_TYPE)
                .form("NONCE", NONCE)
                .form("TOKEN", loginAccessToken);
    }

    public static String getSign(JSONObject bizContent) {
        Map<String, String> paramsMap = new HashMap<String, String>(10);
        paramsMap.put("bizContent", JSONUtil.toJsonPrettyStr(bizContent));
        paramsMap.put("APP_ID", APP_ID);
        paramsMap.put("TIMESTAMP", TIMESTAMP);
        paramsMap.put("SIGN_TYPE", SIGN_TYPE);
        paramsMap.put("NONCE", NONCE);
        return getSign(paramsMap, secret);
    }

    public static String getSignWithToken(JSONObject bizContent) {
        Map<String, String> paramsMap = new HashMap<String, String>(10);
        paramsMap.put("bizContent", JSONUtil.toJsonPrettyStr(bizContent));
        paramsMap.put("APP_ID", APP_ID);
        paramsMap.put("TIMESTAMP", TIMESTAMP);
        paramsMap.put("SIGN_TYPE", SIGN_TYPE);
        paramsMap.put("NONCE", NONCE);
        paramsMap.put("TOKEN", loginAccessToken);
        return getSign(paramsMap, secret);
    }

    public static String getSign(String bizContent) {
        Map<String, String> paramsMap = new HashMap<String, String>(10);
        paramsMap.put("bizContent", bizContent);
        paramsMap.put("APP_ID", APP_ID);
        paramsMap.put("TIMESTAMP", TIMESTAMP);
        paramsMap.put("SIGN_TYPE", SIGN_TYPE);
        paramsMap.put("NONCE", NONCE);
        return getSign(paramsMap, secret);
    }

    public static String getSign(Map<String, String> paramMap, String clientSecret) {
        if (paramMap == null) {
            return "";
        } else {
            Set<String> keySet = paramMap.keySet();
            String[] keyArray = (String[])keySet.toArray(new String[keySet.size()]);
            Arrays.sort(keyArray);
            StringBuilder sb = new StringBuilder();
            String signType = (String)paramMap.get("SIGN_TYPE");
            SignType type = null;
            if (StringUtils.isNotBlank(signType)) {
                type = SignType.valueOf(signType);
            }

            if (type == null) {
                type = SignType.MD5;
            }

            String[] var7 = keyArray;
            int var8 = keyArray.length;

            for(int var9 = 0; var9 < var8; ++var9) {
                String k = var7[var9];
                if (!k.equals("SIGN") && !k.equals("SECRET_KEY") && ((String)paramMap.get(k)).trim().length() > 0) {
                    sb.append(k).append("=").append(((String)paramMap.get(k)).trim()).append("&");
                }
            }
            sb.append("SECRET_KEY=").append(clientSecret);
            return Hex.encodeHexString(sha256(sb.toString())).toUpperCase();
        }
    }

    public static enum SignType {
        MD5,
        SHA256;

        private SignType() {
        }

        public static boolean contains(String type) {
            SignType[] var1 = values();
            int var2 = var1.length;
            for(int var3 = 0; var3 < var2; ++var3) {
                SignType typeEnum = var1[var3];
                if (typeEnum.name().equals(type)) {
                    return true;
                }
            }
            return false;
        }
    }
}
